/* Zatok - язык программирования текстовых игр
 * (С) 2010 - 2012 Меркулов Матвей Юрьевич
 * Код лицензирован под лицензией GNU LGPL
 * Вы можете прочитать текст лицензии по адресу:
 * http://www.gnu.org/copyleft/lesser.html
 * или прочитать русский перевод по адресу:
 * http://ru.wikisource.org/wiki/GNU_Lesser_General_Public_License
 */

package base.userfunction;

import base.CObject;
import base.CProject;
import base.module.CModule;
import java.util.HashMap;
import java.util.LinkedList;
import parser.CCase;
import parser.CParser;

public class CUserFunction extends CObject {
	public HashMap<String, CFunctionParameter> Parameters = new HashMap<String, CFunctionParameter>();
	public CFunctionParameter ParamArray[];
	public LinkedList<CModule> Modules = new LinkedList<CModule>();



	public static void ParseHeader( LinkedList<String> Tokens ) {
		if ( Tokens.size() < 2 ) CParser.Error();
		
		CUserFunction Function = new CUserFunction();

		LinkedList<CFunctionParameter> ParamList = new LinkedList<CFunctionParameter>();
		int TokensQuantity = Tokens.size();
		int Num = 0;
		for ( int VarIndex = 3; VarIndex < TokensQuantity - 1; VarIndex += 2 ) {
			if ( VarIndex > 3 ) {
				if ( !Tokens.get( VarIndex - 1 ).equals( "," ) ) CParser.Error( "Неправильный разделитель, ожидается запятая" );
			}

			CFunctionParameter Parameter = new CFunctionParameter();
			Parameter.ParamNum = Num;
			for( String DeclinedName : CCase.DeclinedNames( Tokens.get( VarIndex ), false ) ) {
				Function.Parameters.put( DeclinedName, Parameter );
			}
			ParamList.add( Parameter );

			Num++;
		}
		Function.ParamArray = new CFunctionParameter[ ParamList.size() ];
		ParamList.toArray( Function.ParamArray );
		
		HashMap<Integer, CUserFunction> Map = CParser.UserFunctions.get( CParser.CurrentReader.CurrentFileNumber );
		if( Map == null ) {
			Map = new HashMap<Integer, CUserFunction>();
			CParser.UserFunctions.put( CParser.CurrentReader.CurrentFileNumber, Map );
		}
		Map.put( CParser.CurrentReader.CurrentLineNumber, Function );
	}



	@Override
	public CObject Parse( LinkedList<String> Tokens ) {
		if ( CParser.CurrentFunction != null ) CParser.Error( "Вложенная функция" );
		if ( CParser.CurrentCommand != null ) CParser.Error( "Функция вложена в команду" );

		CUserFunction Function = CParser.UserFunctions.get( CParser.CurrentReader.CurrentFileNumber ).get( CParser.CurrentReader.CurrentLineNumber );
		
		if( CProject.CurrentObject == null ) {
			CParser.AddUserFunction( CProject.RootObject, Function, Tokens.get( 1 ).toLowerCase(), Function.ParamArray.length );
		} else {
			CParser.AddUserFunction( CProject.CurrentObject, Function, Tokens.get( 1 ).toLowerCase(), Function.ParamArray.length );
		}
		
		CParser.CurrentFunction = Function;

		ParseModules( Function.Modules, "функции", "КонецФункции" );

		CParser.CurrentFunction = null;
		return null;
	}
}
